package imgshare.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import imgshare.common.api.CommonResult;
import imgshare.common.api.ResultCode;
import imgshare.common.exception.ApiException;
import imgshare.model.User;
import imgshare.model.vo.UserAccountForm;
import imgshare.model.vo.UserInfo;
import imgshare.model.vo.UserSecurityForm;
import imgshare.service.UserService;
import imgshare.util.MailUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

import static com.google.common.base.Verify.verify;

@RestController
@RequestMapping("/users")
public class UserController {

    @Value("${front.url}")
    private String FRONT_URL;
    @Value("${ftp.host}")
    private String FTP_HOST;
    @Value("${ftp.port}")
    private Integer FTP_PORT;
    @Value("${ftp.user}")
    private String FTP_USER;
    @Value("${ftp.password}")
    private String FTP_PASSWORD;
    private final static Log log = LogFactory.get();
    @Autowired
    private UserService userService;
    @Autowired
    private MailUtil mailUtil;

    @GetMapping
    public CommonResult<List<User>> list() {
        List<User> userList = userService.findAll();
        return CommonResult.success(userList);
    }

    @GetMapping("/{id}")
    public CommonResult<User> findOne(@PathVariable Integer id) {
        User user = userService.findOne(id);
        return CommonResult.success(user);
    }


    @RequiresAuthentication
    @PostMapping("/account_update")
    public CommonResult<User> updateAccount(@Validated @RequestBody UserAccountForm userAccountForm) {

        User foundedUser = userService.findByEmail(userAccountForm.getEmail());
        // 判断email是否已注册，如已注册，注册者为其它用户则抛出异常
        if (foundedUser != null) {
            if (!foundedUser.getId().equals(userAccountForm.getId())) {
                throw new ApiException("邮箱已注册");
            }
        }

        User user = new User();
        BeanUtil.copyProperties(userAccountForm,user);
        userService.update(user);
        log.info("用户[id:{}]更新用户信息成功",userAccountForm.getId());

        foundedUser = userService.findOne(userAccountForm.getId());
        return CommonResult.success(foundedUser);
    }

    @RequiresAuthentication
    @PostMapping("/avatar_upload")
    public CommonResult<?> uploadAvatar(@RequestParam MultipartFile file) {

        if (file.isEmpty()) return CommonResult.failed(ResultCode.VALIDATE_FAILED);

        User user = new User();
        user.setId(((UserInfo)SecurityUtils.getSubject().getPrincipal()).getId());
        String suffix = FileUtil.getSuffix(file.getOriginalFilename());
        String imageName = IdUtil.simpleUUID() + "." + suffix;
        String imageUrl = FRONT_URL + "avatar/" + imageName;
        user.setAvatar(imageUrl);
        try {
            Ftp ftp = new Ftp(FTP_HOST, FTP_PORT, FTP_USER, FTP_PASSWORD);
            ftp.getClient().enterLocalPassiveMode();
            ftp.upload("./imgshare/avatar",imageName,file.getInputStream());
            ftp.close();
        } catch (IOException e) {
            log.error(e);
            return CommonResult.failed();
        }
        // 文件成功上传后更新数据库
        userService.update(user);

        return CommonResult.success("上传头像成功");
    }

    @RequiresAuthentication
    @PostMapping("/password_reset")
    public CommonResult<?> resetPassword(@RequestBody @Validated UserSecurityForm userSecurityForm) {
        User foundedUser = userService.findOne(userSecurityForm.getUserId());
        assert foundedUser != null;

        boolean samePassword = StrUtil.equals(userSecurityForm.getOldPassword(), userSecurityForm.getNewPassword());
        verify(!samePassword,"旧密码与新密码相同");

        boolean passwordMatched = BCrypt.checkpw(userSecurityForm.getOldPassword(), foundedUser.getPassword());
        verify(passwordMatched,"密码错误");

        User user = new User();
        user.setId(userSecurityForm.getUserId());
        String hashpw = BCrypt.hashpw(userSecurityForm.getNewPassword());
        user.setPassword(hashpw);

        userService.update(user);
        log.info("用户[id:{}]更新密码成功");

        return CommonResult.success("更新密码成功");

    }

    @GetMapping("/password_reset_by_sending_email")
    public CommonResult<?> resetPassword2(@RequestParam String email) {

        Boolean exist = userService.existByEmail(email);
        verify(exist,"邮箱地址不存在");
        //todo
        return null;
    }

    @GetMapping("/{userId}/followed_by_me")
    public CommonResult<List<User>> myFollowingUsers(@PathVariable Integer userId) {
        List<User> users = userService.findMyFollowingUsers(userId);
        return CommonResult.success(users);
    }
}
